この言語の標準API、特定のzipファイルが読めないんだが?
概要
ある言語でunzipできないzipファイルが見つかり、
シグニチャにpk34って書いてあるんで確実にzipだと思うんだが、実際にunzipできるかというとできない。
この謎を追う。
終わりのあたりにはpk78がある。うーん、他のヘッダは存在しないんだよなあ。なんなんだこれ。
-> 先にネタバレしておくと言語側の標準ライブラリがうんこだった。データディスクリプタありのzipをunzipできないんだってさ。ふーん。
解読
http://www.asahi-net.or.jp/~wr9k-oohs/Pages/Nigel%27s/Nigel57/nigel57.html 曰く、
pk34あるいはpk78がヘッダに入ることがある、、、?
よーわからんな、、
https://runicalp.hatenablog.com/entry/20100625/1277471095 曰く、
データディスクリプタっつーのがつくことがある、と。
・ローカルヘッダシグネチャ pk34
・データディスクリプタシグネチャ pk78
あーーーもしかしてzipだと思って接してたけどjarなのかこれ?馬鹿?
ローカルファイルヘッダ(pk34)にcrcとサイズが未定義の場合、このヘッダが定義される。ほー。
https://www.tnksoft.com/reading/zipfile/index.php?p=fmt5 曰く、
pk78のあとに入っているものは
・crc32 4byte
・圧縮後サイズ 4byte
・圧縮前サイズ 4byte
が入ってると。なるほど。
細かいフラグはここを参照するとして
https://gist.github.com/ysakasin/2edf8d3bf55c6ebf63f82851e302b030
っつーことで、RFCとかにも普通に書いてある事態だった。それなのに展開できないライブラリがあるのか。ふーん。
とりあえず引き続き値を読んでいく。
実際の値
50 4B 03 04 //4byte pk34
14 00 //2byte ver
08 08 //2byte general purpose bit flag
08 00 //2byte 圧縮方式 = deflated
xx xx //2byte 更新日時
xx xx //2byte 更新日
00 00 ~
00 00 //4byte crc値
00 00 ~
00 00 //4byte 圧縮後サイズ
00 00 ~
00 00 //4byte 圧縮前サイズ
xx xx //2byte ファイル名長さ
0000 //拡張データサイズ
このへんからファイル名~
で、ビットフラグが0808なので、これは
0010 0010 で、3ビット目と7ビット目がたっている。
3bit目が立っている場合、データディスクリプタが書かれている。
~
50 4B 07 08 //pk78
xx xx xx xx //crc
xx xx xx xx //圧縮後サイズ
xx xx xx xx //圧縮前サイズ
なるほど。まあうーん変わった仕様だとは思うけど末尾に書けるとうれしいもんな、っていう、はい。RFCにも書いてある。
んでこれが読めないライブラリがあると。なるほどなあ。
ファイル名が書いてあってデータがあって長さは、、みたいなのが読めれば、あとはdeflateすればいいだけっぽいし。
-> できました。
いい話。